package com.example.discover.viewmodel

import android.util.Log
import androidx.lifecycle.*
import com.example.featuresdk.model.Book
import com.example.discover.repository.BookRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class BookViewModel @Inject constructor(private val repository: BookRepository): ViewModel() {

    lateinit var books: LiveData<List<Book>>

    init {
        Log.i("BookViewModel","***BookViewModel instance is created***")

//        viewModelScope.async {
//            books = repository.fetch()
//        }
        viewModelScope.launch(Dispatchers.Unconfined) {
            books = repository.getAll(viewModelScope)
        }
    }

//    val book : LiveData<Book> by lazy {
//        Transformations.map(books){ it -> if (it.isEmpty()) { Book("","","") } else { it.lastOrNull()} }
//    }

//    val totalPrice: LiveData<String> by lazy {
//        Transformations.switchMap(books) { it -> calTotalPrice(it) }
//    }
//
//    val totalSize: LiveData<String> by lazy {
//        Transformations.switchMap(books){ it -> MutableLiveData<String> (it.size.toString())}
//    }

//    companion object {
//        fun calTotalPrice(books: List<Book>): LiveData<String> {
//            var sum = 0
//            books.forEach {
//                if (it.price.isDigitsOnly()) {
//                    sum += it.price.toInt()
//                }
//            }
//            return MutableLiveData<String> (sum.toString())
//        }
//    }
    /**
     * Launching a new coroutine to insert the data in a non-blocking way
     *
     * viewModelScope is a CoroutineScope tied to this ViewModel.
     * This scope will be canceled when ViewModel will be cleared, i.e ViewModel.onCleared is called.
     * This scope is bound to Dispatchers.Main.immediate
     *
     * viewModelScope launches a new coroutine without blocking the current thread
     * and returns a reference to the coroutine as a Job.
     * The coroutine is cancelled when the resulting job is cancelled.
     */
    fun add(book: Book) =  viewModelScope.launch{
        repository.insert(*arrayOf(book))
    }

    fun remove(isbn: String) =  viewModelScope.launch{
        repository.delete(isbn)
    }

    fun updatePrice(isbn:String, price:String) =  viewModelScope.launch{
        repository.update(isbn,price)
    }

    fun update(book: Book) =  viewModelScope.launch{
        repository.update(book)
    }

    fun refresh() = viewModelScope.launch {

//        var _books : List<Book>
//         repository.getAll().collect {
//             _books = it
//        }
    }

    override fun onCleared() {
        Log.i("BookViewModel","onCleared() ${this.toString()}")
    }
}